package se.webbzon.boltzmann.world;

import java.util.Collection;

import se.webbzon.boltzmann.game.character.CharacterException;
import se.webbzon.boltzmann.game.environment.GameEnvironment;
import se.webbzon.boltzmann.game.object.camera.GameCamera;
import se.webbzon.boltzmann.game.object.inventory.GameInventory;
import se.webbzon.boltzmann.game.object.player.AbstractPlayerCharacter;
import se.webbzon.boltzmann.game.object.portal.AbstractPortal;
import se.webbzon.boltzmann.hud.BlackOverlay;
import se.webbzon.boltzmann.object.escaper.DefaultEscaper;
import se.webbzon.boltzmann.player.Player;
import se.webbzon.oschi01.worldarea.WorldArea;

public class GameWorldLoader extends AbstractWorldLoader {
	
	// The player associated with this game world loader
	private final Player player;
	
	// The id of the portal used for player spawning
	private final byte portalId;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public GameWorldLoader(	GameEnvironment env, 
							String worldAreaName,
							Player player,
							byte portalId) {
		super(env,worldAreaName);
		this.player = player;
		this.portalId = portalId;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the player associated with this game world loader. **/
	public Player getPlayer() {
		return player;
	}
	
	/** Returns the id of the portal used for player spawning. **/
	public byte getPortalId() {
		return portalId;
	}
	
	@Override public WorldArea load() throws WorldLoaderException {
		GameEnvironment env = (GameEnvironment) getEnvironment();
		WorldArea world = super.load();
		
		// Add an escaper to the world
		world.createInstance(new DefaultEscaper());
		
		// Add a black overlay
		world.createInstance(new BlackOverlay());
		
		Collection<AbstractPortal> portals = 
				world.findInstances(AbstractPortal.class);
		
		try { 
			for (AbstractPortal portal : portals)
				if (portal.getPortalId() == getPortalId()) {
					AbstractPlayerCharacter playerCharacter = 
							AbstractPlayerCharacter.makePlayerCharacter(player);
					world.createInstance(playerCharacter);
					GameCamera camera = new GameCamera(player,playerCharacter);
					camera.addView(player.getView());
					world.createInstance(camera);
					world.createInstance(new GameInventory(playerCharacter,env.getInventoryLayout()));
					portal.spawn(playerCharacter);
					break;
					
				}
		} catch (CharacterException e) {
			throw new WorldLoaderException(e);
		}
		
		// Update the location of the player
		String worldAreaName = getWorldAreaName();
		RegionEnum region = RegionEnum.fromWorldAreaName(worldAreaName);
		player.getLocation().setRegion(region);
		player.getLocation().setWorldAreaName(worldAreaName);
		player.getLocation().setPortalId(portalId);
		
		return world;
	}

}
